package com.example.housingRentalSystem.utils;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author 王硕
 * @version jdk21
 * @className ApiResponse
 * @description
 * @date 2025/3/6 9:03
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ApiResponse<T>{
    // 状态码
    private Integer code;
    // 消息
    private String message;
    //数据
    private T data;

    /**
     * 创建一个成功的API响应对象，包含数据
     *
     * @param data API响应中的数据
     * @param <T> 泛型参数，表示API响应中数据的类型
     * @return 成功的API响应对象，包含HTTP状态码200和默认的成功消息
     */
    public static <T> ApiResponse<T> success(T data){
        return new ApiResponse<>(HttpStatus.OK.getCode(), HttpStatus.OK.getMessage(), data);
    }

    /**
     * 创建一个成功的API响应对象，包含数据和自定义消息
     *
     * @param data API响应中的数据
     * @param message 自定义的成功消息
     * @param <T> 泛型参数，表示API响应中数据的类型
     * @return 成功的API响应对象，包含HTTP状态码200和自定义的成功消息
     */
    public static <T> ApiResponse<T> success(String message, T data) {
        return new ApiResponse<>(HttpStatus.OK.getCode(), message, data);
    }

    /**
     * 创建一个错误的API响应对象
     *
     * @param code 错误状态码
     * @param message 错误消息
     * @param <T> 泛型参数，表示API响应中数据的类型
     * @return 错误的API响应对象，不包含数据
     */
    public static <T> ApiResponse<T> error(Integer code, String message) {
        return new ApiResponse<>(code, message, null);
    }

    /**
     * 创建一个错误的API响应对象，包含错误数据
     *
     * @param code 错误状态码
     * @param message 错误消息
     * @param data 错误数据
     * @param <T> 泛型参数，表示API响应中数据的类型
     * @return 错误的API响应对象，包含错误数据
     */
    public static <T> ApiResponse<T> error(Integer code, String message, T data) {
        return new ApiResponse<>(code, message, data);
    }

    // 添加带状态码的成功响应方法
    public static <T> ApiResponse<T> success(Integer code, String message, T data) {
        return new ApiResponse<>(code, message, data);
    }

    // 添加带状态码的无数据成功响应
    public static ApiResponse<Void> success(Integer code, String message) {
        return new ApiResponse<>(code, message, null);
    }
    /**
     * 创建一个表示坏请求的ApiResponse对象
     * <p>
     * 此方法用于生成一个HTTP状态码为400（坏请求）的ApiResponse对象它表示客户端发送的请求有语法错误，
     * 或不能被服务器理解并处理
     *
     * @param message 错误信息，描述坏请求的具体原因
     * @param <T> 泛型参数，表示响应体中可能携带的数据类型
     * @return 返回一个包含错误信息和状态码的ApiResponse对象
     */
    public static <T> ApiResponse<T> badRequest(String message) {
        return new ApiResponse<>(HttpStatus.BAD_REQUEST.getCode(), message, null);
    }

    /**
     * 创建一个表示未授权的ApiResponse对象
     * <p>
     * 此方法用于生成一个HTTP状态码为401（未授权）的ApiResponse对象它表示客户端尝试访问受保护的资源，
     * 但未提供正确的身份验证凭据
     *
     * @param message 错误信息，描述未授权访问的具体原因
     * @param <T> 泛型参数，表示响应体中可能携带的数据类型
     * @return 返回一个包含错误信息和状态码的ApiResponse对象
     */
    public static <T> ApiResponse<T> unauthorized(String message) {
        return new ApiResponse<>(HttpStatus.UNAUTHORIZED.getCode(), message, null);
    }

    /**
     * 创建一个表示禁止访问的ApiResponse对象
     * <p>
     * 此方法用于生成一个HTTP状态码为403（禁止访问）的ApiResponse对象它表示客户端已经通过了身份验证，
     * 但没有足够的权限访问请求的资源
     *
     * @param message 错误信息，描述禁止访问的具体原因
     * @param <T> 泛型参数，表示响应体中可能携带的数据类型
     * @return 返回一个包含错误信息和状态码的ApiResponse对象
     */
    public static <T> ApiResponse<T> forbidden(String message) {
        return new ApiResponse<>(HttpStatus.FORBIDDEN.getCode(), message, null);
    }

    /**
     * 创建一个表示未找到资源的ApiResponse对象
     * <p>
     * 此方法用于生成一个HTTP状态码为404（未找到）的ApiResponse对象它表示客户端请求的资源在服务器上不存在
     *
     * @param message 错误信息，描述未找到资源的具体原因
     * @param <T> 泛型参数，表示响应体中可能携带的数据类型
     * @return 返回一个包含错误信息和状态码的ApiResponse对象
     */
    public static <T> ApiResponse<T> notFound(String message) {
        return new ApiResponse<>(HttpStatus.NOT_FOUND.getCode(), message, null);
    }

    /**
     * 创建一个表示内部服务器错误的ApiResponse对象
     * <p>
     * 此方法用于生成一个HTTP状态码为500（内部服务器错误）的ApiResponse对象它表示服务器在处理请求时遇到了错误，
     * 无法完成请求
     *
     * @param message 错误信息，描述内部服务器错误的具体原因
     * @param <T> 泛型参数，表示响应体中可能携带的数据类型
     * @return 返回一个包含错误信息和状态码的ApiResponse对象
     */
    public static <T> ApiResponse<T> internalServerError(String message) {
        return new ApiResponse<>(HttpStatus.INTERNAL_SERVER_ERROR.getCode(), message, null);
    }
}
